home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / r_surf.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  15KB  |  701 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // r_surf.c: surface-related refresh code
  21.  
  22. #include "quakedef.h"
  23. #include "r_local.h"
  24.  
  25. drawsurf_t    r_drawsurf;
  26.  
  27. static int                sourcesstep, blocksize, sourcetstep;
  28. int                lightdelta, lightdeltastep;
  29. static int                blockdivshift;
  30. static void            *prowdestbase;
  31. static unsigned char    *pbasesource;
  32. static int                surfrowbytes;    // used by ASM files
  33. static unsigned        *r_lightptr;
  34. static int                r_stepback;
  35. static int                r_lightwidth;
  36. static int                r_numhblocks, r_numvblocks;
  37. static unsigned char    *r_source, *r_sourcemax;
  38.  
  39. void R_DrawSurfaceBlock8_mip0 (void);
  40. void R_DrawSurfaceBlock8_mip1 (void);
  41. void R_DrawSurfaceBlock8_mip2 (void);
  42. void R_DrawSurfaceBlock8_mip3 (void);
  43.  
  44. static void    (*surfmiptable[4])(void) = {
  45.     R_DrawSurfaceBlock8_mip0,
  46.     R_DrawSurfaceBlock8_mip1,
  47.     R_DrawSurfaceBlock8_mip2,
  48.     R_DrawSurfaceBlock8_mip3
  49. };
  50.  
  51.  
  52.  
  53. static unsigned        blocklights[18*18];
  54.  
  55. #if id68k
  56. extern void R_AddDynamicLights (void);
  57. #else
  58. /*
  59. ===============
  60. R_AddDynamicLights
  61. ===============
  62. */
  63. void R_AddDynamicLights (void)
  64. {
  65.     msurface_t *surf;
  66.     int            lnum;
  67.     int            sd, td;
  68.     float        dist, rad, minlight;
  69.     vec3_t        impact, local;
  70.     int            s, t;
  71.     int            i;
  72.     int            smax, tmax;
  73.     mtexinfo_t    *tex;
  74.  
  75.     surf = r_drawsurf.surf;
  76.     smax = (surf->extents[0]>>4)+1;
  77.     tmax = (surf->extents[1]>>4)+1;
  78.     tex = surf->texinfo;
  79.  
  80.     for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
  81.     {
  82.         if ( !(surf->dlightbits & (1<<lnum) ) )
  83.             continue;        // not lit by this light
  84.  
  85.         rad = cl_dlights[lnum].radius;
  86.         dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) -
  87.                 surf->plane->dist;
  88.         rad -= fabs(dist);
  89.         minlight = cl_dlights[lnum].minlight;
  90.         if (rad < minlight)
  91.             continue;
  92.         minlight = rad - minlight;
  93.  
  94.         for (i=0 ; i<3 ; i++)
  95.         {
  96.             impact[i] = cl_dlights[lnum].origin[i] -
  97.                     surf->plane->normal[i]*dist;
  98.         }
  99.  
  100.         local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
  101.         local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
  102.  
  103.         local[0] -= surf->texturemins[0];
  104.         local[1] -= surf->texturemins[1];
  105.         
  106.         for (t = 0 ; t<tmax ; t++)
  107.         {
  108.             td = local[1] - t*16;
  109.             if (td < 0)
  110.                 td = -td;
  111.             for (s=0 ; s<smax ; s++)
  112.             {
  113.                 sd = local[0] - s*16;
  114.                 if (sd < 0)
  115.                     sd = -sd;
  116.                 if (sd > td)
  117.                     dist = sd + (td>>1);
  118.                 else
  119.                     dist = td + (sd>>1);
  120.                 if (dist < minlight)
  121. #ifdef QUAKE2
  122.                 {
  123.                     unsigned temp;
  124.                     temp = (rad - dist)*256;
  125.                     i = t*smax + s;
  126.                     if (!cl_dlights[lnum].dark)
  127.                         blocklights[i] += temp;
  128.                     else
  129.                     {
  130.                         if (blocklights[i] > temp)
  131.                             blocklights[i] -= temp;
  132.                         else
  133.                             blocklights[i] = 0;
  134.                     }
  135.                 }
  136. #else
  137.                     blocklights[t*smax + s] += (rad - dist)*256;
  138. #endif
  139.             }
  140.         }
  141.     }
  142. }
  143.  
  144. #endif
  145.  
  146. /*
  147. ===============
  148. R_BuildLightMap
  149.  
  150. Combine and scale multiple lightmaps into the 8.8 format in blocklights
  151. ===============
  152. */
  153. void R_BuildLightMap (void)
  154. {
  155.     int            smax, tmax;
  156.     int            t;
  157.     int            i, size;
  158.     byte        *lightmap;
  159.     unsigned    scale;
  160.     int            maps;
  161.     msurface_t    *surf;
  162.  
  163.     surf = r_drawsurf.surf;
  164.  
  165.     smax = (surf->extents[0]>>4)+1;
  166.     tmax = (surf->extents[1]>>4)+1;
  167.     size = smax*tmax;
  168.     lightmap = surf->samples;
  169.  
  170.     if (r_fullbright.value || !cl.worldmodel->lightdata)
  171.     {
  172.         for (i=0 ; i<size ; i++)
  173.             blocklights[i] = 0;
  174.         return;
  175.     }
  176.  
  177. // clear to ambient
  178.     for (i=0 ; i<size ; i++)
  179.         blocklights[i] = r_refdef.ambientlight<<8;
  180.  
  181.  
  182. // add all the lightmaps
  183.     if (lightmap)
  184.         for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  185.              maps++)
  186.         {
  187.             scale = r_drawsurf.lightadj[maps];    // 8.8 fraction        
  188.             for (i=0 ; i<size ; i++)
  189.                 blocklights[i] += lightmap[i] * scale;
  190.             lightmap += size;    // skip to next lightmap
  191.         }
  192.  
  193. // add all the dynamic lights
  194.     if (surf->dlightframe == r_framecount)
  195.         R_AddDynamicLights ();
  196.  
  197. // bound, invert, and shift
  198.     for (i=0 ; i<size ; i++)
  199.     {
  200.         t = (255*256 - (int)blocklights[i]) >> (8 - VID_CBITS);
  201.  
  202.         if (t < (1 << 6))
  203.             t = (1 << 6);
  204.  
  205.         blocklights[i] = t;
  206.     }
  207. }
  208.  
  209.  
  210. /*
  211. ===============
  212. R_TextureAnimation
  213.  
  214. Returns the proper texture for a given time and base texture
  215. ===============
  216. */
  217. texture_t *R_TextureAnimation (texture_t *base)
  218. {
  219.     int        reletive;
  220.     int        count;
  221.  
  222.     if (currententity->frame)
  223.     {
  224.         if (base->alternate_anims)
  225.             base = base->alternate_anims;
  226.     }
  227.     
  228.     if (!base->anim_total)
  229.         return base;
  230.  
  231.     reletive = (int)(cl.time*10) % base->anim_total;
  232.  
  233.     count = 0;    
  234.     while (base->anim_min > reletive || base->anim_max <= reletive)
  235.     {
  236.         base = base->anim_next;
  237.         if (!base)
  238.             Sys_Error ("R_TextureAnimation: broken cycle");
  239.         if (++count > 100)
  240.             Sys_Error ("R_TextureAnimation: infinite cycle");
  241.     }
  242.  
  243.     return base;
  244. }
  245.  
  246.  
  247. /*
  248. ===============
  249. R_DrawSurface
  250. ===============
  251. */
  252. void R_DrawSurface (void)
  253. {
  254.     unsigned char    *basetptr;
  255.     int                smax, tmax, twidth;
  256.     int                u;
  257.     int                soffset, basetoffset, texwidth;
  258.     int                horzblockstep;
  259.     unsigned char    *pcolumndest;
  260.     void            (*pblockdrawer)(void);
  261.     texture_t        *mt;
  262.     unsigned    blockdivmask;
  263.  
  264. // calculate the lightings
  265.     R_BuildLightMap ();
  266.     
  267.     surfrowbytes = r_drawsurf.rowbytes;
  268.  
  269.     mt = r_drawsurf.texture;
  270.     
  271.     r_source = (byte *)mt + mt->offsets[r_drawsurf.surfmip];
  272.     
  273. // the fractional light values should range from 0 to (VID_GRADES - 1) << 16
  274. // from a source range of 0 - 255
  275.     
  276.     texwidth = mt->width >> r_drawsurf.surfmip;
  277.  
  278.     blocksize = 16 >> r_drawsurf.surfmip;
  279.     blockdivshift = 4 - r_drawsurf.surfmip;
  280.     blockdivmask = (1 << blockdivshift) - 1;
  281.     
  282.     r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1;
  283.  
  284.     r_numhblocks = r_drawsurf.surfwidth >> blockdivshift;
  285.     r_numvblocks = r_drawsurf.surfheight >> blockdivshift;
  286.  
  287. //==============================
  288.  
  289.     if (r_pixbytes == 1)
  290.     {
  291.         pblockdrawer = surfmiptable[r_drawsurf.surfmip];
  292.     // TODO: only needs to be set when there is a display settings change
  293.         horzblockstep = blocksize;
  294.     }
  295.     else
  296.     {
  297.         pblockdrawer = R_DrawSurfaceBlock16;
  298.     // TODO: only needs to be set when there is a display settings change
  299.         horzblockstep = blocksize << 1;
  300.     }
  301.  
  302.     smax = mt->width >> r_drawsurf.surfmip;
  303.     twidth = texwidth;
  304.     tmax = mt->height >> r_drawsurf.surfmip;
  305.     sourcetstep = texwidth;
  306.     r_stepback = tmax * twidth;
  307.  
  308.     r_sourcemax = r_source + (tmax * smax);
  309.  
  310.     soffset = r_drawsurf.surf->texturemins[0];
  311.     basetoffset = r_drawsurf.surf->texturemins[1];
  312.  
  313. // << 16 components are to guarantee positive values for %
  314.     soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
  315.     basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip) 
  316.         + (tmax << 16)) % tmax) * twidth)];
  317.  
  318.     pcolumndest = r_drawsurf.surfdat;
  319.  
  320.     for (u=0 ; u<r_numhblocks; u++)
  321.     {
  322.         r_lightptr = blocklights + u;
  323.  
  324.         prowdestbase = pcolumndest;
  325.  
  326.         pbasesource = basetptr + soffset;
  327.  
  328.         (*pblockdrawer)();
  329.  
  330.         soffset = soffset + blocksize;
  331.         if (soffset >= smax)
  332.             soffset = 0;
  333.  
  334.         pcolumndest += horzblockstep;
  335.     }
  336. }
  337.  
  338.  
  339. //=============================================================================
  340.  
  341. #if    !id386
  342. #if !id68k
  343.  
  344. /*
  345. ================
  346. R_DrawSurfaceBlock8_mip0
  347. ================
  348. */
  349. void R_DrawSurfaceBlock8_mip0 (void)
  350. {
  351.     int    v;
  352.     int    psourcestep, prowdeststep;
  353.     unsigned char    *psource, *prowdest, *colormap;
  354.  
  355.     colormap = (unsigned char *)vid.colormap;
  356.     psourcestep = sourcetstep;
  357.     prowdeststep = surfrowbytes;
  358.     psource = pbasesource;
  359.     prowdest = prowdestbase;
  360.  
  361.     for (v=0 ; v<r_numvblocks ; v++)
  362.     {
  363.         int i, lightleft, lightright, lightleftstep, lightrightstep;
  364.  
  365.     // FIXME: use delta rather than both right and left, like ASM?
  366.         lightleft = r_lightptr[0];
  367.         lightright = r_lightptr[1];
  368.         r_lightptr += r_lightwidth;
  369.         lightleftstep = (r_lightptr[0] - lightleft) >> 4;
  370.         lightrightstep = (r_lightptr[1] - lightright) >> 4;
  371.  
  372.         for (i=0 ; i<16 ; i++)
  373.         {
  374.             int b, lightstep, light;
  375.  
  376.             lightstep = (lightleft - lightright) >> 4;
  377.  
  378.             light = lightright;
  379.  
  380.             for (b=15; b>=0; b--)
  381.             {
  382.                 prowdest[b] = colormap[(light & 0xFF00) + psource[b]];
  383.                 light += lightstep;
  384.             }
  385.     
  386.             psource += psourcestep;
  387.             lightright += lightrightstep;
  388.             lightleft += lightleftstep;
  389.             prowdest += prowdeststep;
  390.         }
  391.  
  392.         if (psource >= r_sourcemax)
  393.             psource -= r_stepback;
  394.     }
  395. }
  396.  
  397.  
  398. /*
  399. ================
  400. R_DrawSurfaceBlock8_mip1
  401. ================
  402. */
  403. void R_DrawSurfaceBlock8_mip1 (void)
  404. {
  405.     int    v;
  406.     int    psourcestep, prowdeststep;
  407.     unsigned char    *psource, *prowdest, *colormap;
  408.  
  409.     colormap = (unsigned char *)vid.colormap;
  410.     psourcestep = sourcetstep;
  411.     prowdeststep = surfrowbytes;
  412.     psource = pbasesource;
  413.     prowdest = prowdestbase;
  414.  
  415.     for (v=0 ; v<r_numvblocks ; v++)
  416.     {
  417.         int i, lightleft, lightright, lightleftstep, lightrightstep;
  418.  
  419.     // FIXME: use delta rather than both right and left, like ASM?
  420.         lightleft = r_lightptr[0];
  421.         lightright = r_lightptr[1];
  422.         r_lightptr += r_lightwidth;
  423.         lightleftstep = (r_lightptr[0] - lightleft) >> 3;
  424.         lightrightstep = (r_lightptr[1] - lightright) >> 3;
  425.  
  426.         for (i=0 ; i<8 ; i++)
  427.         {
  428.             int b, lightstep, light;
  429.  
  430.             lightstep = (lightleft - lightright) >> 3;
  431.  
  432.             light = lightright;
  433.  
  434.             for (b=7; b>=0; b--)
  435.             {
  436.                 prowdest[b] = colormap[(light & 0xFF00) + psource[b]];
  437.                 light += lightstep;
  438.             }
  439.     
  440.             psource += psourcestep;
  441.             lightright += lightrightstep;
  442.             lightleft += lightleftstep;
  443.             prowdest += prowdeststep;
  444.         }
  445.  
  446.         if (psource >= r_sourcemax)
  447.             psource -= r_stepback;
  448.     }
  449. }
  450.  
  451.  
  452. /*
  453. ================
  454. R_DrawSurfaceBlock8_mip2
  455. ================
  456. */
  457. void R_DrawSurfaceBlock8_mip2 (void)
  458. {
  459.     int    v;
  460.     int    psourcestep, prowdeststep;
  461.     unsigned char    *psource, *prowdest, *colormap;
  462.  
  463.     colormap = (unsigned char *)vid.colormap;
  464.     psourcestep = sourcetstep;
  465.     prowdeststep = surfrowbytes;
  466.     psource = pbasesource;
  467.     prowdest = prowdestbase;
  468.  
  469.     for (v=0 ; v<r_numvblocks ; v++)
  470.     {
  471.         int i, lightleft, lightright, lightleftstep, lightrightstep;
  472.  
  473.     // FIXME: use delta rather than both right and left, like ASM?
  474.         lightleft = r_lightptr[0];
  475.         lightright = r_lightptr[1];
  476.         r_lightptr += r_lightwidth;
  477.         lightleftstep = (r_lightptr[0] - lightleft) >> 2;
  478.         lightrightstep = (r_lightptr[1] - lightright) >> 2;
  479.  
  480.         for (i=0 ; i<4 ; i++)
  481.         {
  482.             int b, lightstep, light;
  483.  
  484.             lightstep = (lightleft - lightright) >> 2;
  485.  
  486.             light = lightright;
  487.  
  488.             for (b=3; b>=0; b--)
  489.             {
  490.                 prowdest[b] = colormap[(light & 0xFF00) + psource[b]];
  491.                 light += lightstep;
  492.             }
  493.     
  494.             psource += psourcestep;
  495.             lightright += lightrightstep;
  496.             lightleft += lightleftstep;
  497.             prowdest += prowdeststep;
  498.         }
  499.  
  500.         if (psource >= r_sourcemax)
  501.             psource -= r_stepback;
  502.     }
  503. }
  504.  
  505.  
  506. /*
  507. ================
  508. R_DrawSurfaceBlock8_mip3
  509. ================
  510. */
  511. void R_DrawSurfaceBlock8_mip3 (void)
  512. {
  513.     int    v;
  514.     int    psourcestep, prowdeststep;
  515.     unsigned char    *psource, *prowdest, *colormap;
  516.  
  517.     colormap = (unsigned char *)vid.colormap;
  518.     psourcestep = sourcetstep;
  519.     prowdeststep = surfrowbytes;
  520.     psource = pbasesource;
  521.     prowdest = prowdestbase;
  522.  
  523.     for (v=0 ; v<r_numvblocks ; v++)
  524.     {
  525.         int i, lightleft, lightright, lightleftstep, lightrightstep;
  526.  
  527.     // FIXME: use delta rather than both right and left, like ASM?
  528.         lightleft = r_lightptr[0];
  529.         lightright = r_lightptr[1];
  530.         r_lightptr += r_lightwidth;
  531.         lightleftstep = (r_lightptr[0] - lightleft) >> 1;
  532.         lightrightstep = (r_lightptr[1] - lightright) >> 1;
  533.  
  534.         for (i=0 ; i<2 ; i++)
  535.         {
  536.             int b, lightstep, light;
  537.  
  538.             lightstep = (lightleft - lightright) >> 1;
  539.  
  540.             light = lightright;
  541.  
  542.             for (b=1; b>=0; b--)
  543.             {
  544.                 prowdest[b] = colormap[(light & 0xFF00) + psource[b]];
  545.                 light += lightstep;
  546.             }
  547.     
  548.             psource += psourcestep;
  549.             lightright += lightrightstep;
  550.             lightleft += lightleftstep;
  551.             prowdest += prowdeststep;
  552.         }
  553.  
  554.         if (psource >= r_sourcemax)
  555.             psource -= r_stepback;
  556.     }
  557. }
  558.  
  559.  
  560. /*
  561. ================
  562. R_DrawSurfaceBlock16
  563.  
  564. FIXME: make this work
  565. ================
  566. */
  567. void R_DrawSurfaceBlock16 (void)
  568. {
  569.     int                k;
  570.     unsigned char    *psource;
  571.     int                lighttemp, lightstep, light;
  572.     unsigned short    *prowdest;
  573.     int    lightleft, lightright, lightleftstep, lightrightstep;
  574.  
  575.     prowdest = (unsigned short *)prowdestbase;
  576.  
  577.     for (k=0 ; k<blocksize ; k++)
  578.     {
  579.         unsigned short    *pdest;
  580.         int                b;
  581.  
  582.         psource = pbasesource;
  583.         lighttemp = lightright - lightleft;
  584.         lightstep = lighttemp >> blockdivshift;
  585.  
  586.         light = lightleft;
  587.         pdest = prowdest;
  588.  
  589.         for (b=0; b<blocksize; b++)
  590.         {
  591.             *pdest = vid.colormap16[(light & 0xFF00) + *psource];
  592.             psource += sourcesstep;
  593.             pdest++;
  594.             light += lightstep;
  595.         }
  596.  
  597.         pbasesource += sourcetstep;
  598.         lightright += lightrightstep;
  599.         lightleft += lightleftstep;
  600.         prowdest = (unsigned short *)((long)prowdest + surfrowbytes);
  601.     }
  602.  
  603.     prowdestbase = prowdest;
  604. }
  605.  
  606. #endif
  607. #endif
  608.  
  609.  
  610. //============================================================================
  611.  
  612. /*
  613. ================
  614. R_GenTurbTile
  615. ================
  616. */
  617. void R_GenTurbTile (pixel_t *pbasetex, void *pdest)
  618. {
  619.     int        *turb;
  620.     int        i, j, s, t;
  621.     byte    *pd;
  622.     
  623.     turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  624.     pd = (byte *)pdest;
  625.  
  626.     for (i=0 ; i<TILE_SIZE ; i++)
  627.     {
  628.         for (j=0 ; j<TILE_SIZE ; j++)
  629.         {    
  630.             s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
  631.             t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
  632.             *pd++ = *(pbasetex + (t<<6) + s);
  633.         }
  634.     }
  635. }
  636.  
  637.  
  638. /*
  639. ================
  640. R_GenTurbTile16
  641. ================
  642. */
  643. void R_GenTurbTile16 (pixel_t *pbasetex, void *pdest)
  644. {
  645.     int                *turb;
  646.     int                i, j, s, t;
  647.     unsigned short    *pd;
  648.  
  649.     turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  650.     pd = (unsigned short *)pdest;
  651.  
  652.     for (i=0 ; i<TILE_SIZE ; i++)
  653.     {
  654.         for (j=0 ; j<TILE_SIZE ; j++)
  655.         {    
  656.             s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
  657.             t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
  658.             *pd++ = d_8to16table[*(pbasetex + (t<<6) + s)];
  659.         }
  660.     }
  661. }
  662.  
  663.  
  664. /*
  665. ================
  666. R_GenTile
  667. ================
  668. */
  669. void R_GenTile (msurface_t *psurf, void *pdest)
  670. {
  671.     if (psurf->flags & SURF_DRAWTURB)
  672.     {
  673.         if (r_pixbytes == 1)
  674.         {
  675.             R_GenTurbTile ((pixel_t *)
  676.                 ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
  677.         }
  678.         else
  679.         {
  680.             R_GenTurbTile16 ((pixel_t *)
  681.                 ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
  682.         }
  683.     }
  684.     else if (psurf->flags & SURF_DRAWSKY)
  685.     {
  686.         if (r_pixbytes == 1)
  687.         {
  688.             R_GenSkyTile (pdest);
  689.         }
  690.         else
  691.         {
  692.             R_GenSkyTile16 (pdest);
  693.         }
  694.     }
  695.     else
  696.     {
  697.         Sys_Error ("Unknown tile type");
  698.     }
  699. }
  700.  
  701.